#include "VulkanApplication.h"
#include <vector>
#include <iostream>

VulkanApplication::VulkanApplication(const char* appName)
    : _instance(nullptr)
{
    if (!glfwInit())
    {
        printf("Failed to initialize GLFW.\n");
        _initialized = false; return;
    }

    if (!glfwVulkanSupported())
    {
        printf("Vulkan not supported.\n");
        _initialized = false; return;
    }

    _initialized = createInstance(appName);
}

VulkanApplication::~VulkanApplication()
{
    if (_instance != nullptr) vkDestroyInstance(_instance, nullptr);
    glfwTerminate();
}

bool VulkanApplication::createInstance(const char* appName)
{
    uint32_t glfwExtCount = 0;
    const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtCount);
    printf("GLFW initialized. It requires the following extensions:\n");
    for (uint32_t i = 0; i < glfwExtCount; i++)
        printf("    %s\n", glfwExtensions[i]);

    const char* layerNames[] =
    {
        "VK_LAYER_KHRONOS_validation"
    };

    VkApplicationInfo appInfo
    {
        VK_STRUCTURE_TYPE_APPLICATION_INFO,
        nullptr,
        appName,
        VK_MAKE_VERSION(1, 0, 0),
        "VulkanClass",
        VK_MAKE_VERSION(1, 0, 0),
        VK_API_VERSION_1_3,
    };

    VkInstanceCreateInfo instanceInfo
    {
        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
        nullptr, 0,
        &appInfo,
        1, layerNames,
        glfwExtCount, glfwExtensions
    };

    VkResult result = vkCreateInstance(&instanceInfo, nullptr, &_instance);
    if (result != VK_SUCCESS)
    {
        printf("Vulkan instance creation failed: %d\n", result);
        return false;
    }
    return true;
}
